import { createI18n, type LocaleMessages } from 'vue-i18n'
import { nextTick, type Ref } from 'vue'

import en from 'element-plus/dist/locale/en'
import zhHk from 'element-plus/dist/locale/zh-hk'
import zhCn from 'element-plus/dist/locale/zh-cn'
import type { MessageSchema } from '@/types/i18n'

// 1. 声明所有支持的语言类型
export type SupportedLocales = 'en' | 'zh-hk' | 'zh-cn'
export const langList: { [key in SupportedLocales]: string } = {
    en: 'English',
    'zh-hk': '繁體中文',
    'zh-cn': '简体中文',
}

// 2. 从 localStorage 读取用户上次选择的语言，如果没有则使用默认语言
export function getSavedLocale(): SupportedLocales {
    const savedLocale = localStorage.getItem('userLocale') as SupportedLocales
    document.querySelector('html')?.setAttribute('lang', savedLocale || 'zh-hk')
    return savedLocale && Object.keys(langList).includes(savedLocale) ? savedLocale : 'zh-hk'
}

// 3. 创建强类型的 i18n 实例
const i18n = createI18n<
    {
        message: MessageSchema
        datetime?: never
        number?: never
    },
    SupportedLocales
>({
    legacy: false,
    locale: getSavedLocale(), // 初始化时读取存储的语言
    fallbackLocale: 'zh-hk',
    messages: {
        en: {
            ...en,
        },
        'zh-hk': {
            ...zhHk,
        },
        'zh-cn': {
            ...zhHk,
        },
    } as Record<SupportedLocales, LocaleMessages<MessageSchema>>,
    missingWarn: false,
}) as any

// 4. 异步加载自定义语言包
export async function loadLocaleMessages(locale: SupportedLocales): Promise<void> {
    try {
        const messages = await import(`@/locales/lang/${locale}.json`)
        // 合并 Element Plus 语言包和自定义语言包
        i18n.global.setLocaleMessage(locale, {
            ...i18n.global.getLocaleMessage(locale), // 保留已加载的 Element 语言包
            ...messages.default, // 添加自定义语言包
        })
    } catch (error) {
        console.error(`Failed to load ${locale} messages:`, error)
        throw error
    }
}

// 5. 切换语言并存储用户选择
export async function setLocale(locale: SupportedLocales): Promise<void> {
    if (i18n.global.locale === locale) return

    await loadLocaleMessages(locale) // 确保语言包已加载
    i18n.global.locale = locale
    localStorage.setItem('userLocale', locale)

    // 更新 Element Plus 的语言配置
    document.querySelector('html')?.setAttribute('lang', locale)

    // 强制更新所有依赖 i18n 的组件
    await nextTick()
    window.dispatchEvent(new Event('language-changed'))
}

// 6. 初始化时加载默认语言包
loadLocaleMessages(getSavedLocale()).catch(console.error)

// 7. 导出 Element Plus 的语言配置
export const getElementPlusLocale = () => {
    switch (i18n.global.locale.value) {
        case 'en':
            return en
        case 'zh-cn':
            return zhCn
        default:
            return zhHk
    }
}

export const getElementPlusI18nT = () => {
    return (key: string) => i18n.global.t(key)
}

export default i18n
